package cn.com.easy.permission.web.filter;

import java.io.IOException;
import java.util.List;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import cn.com.easy.permission.model.UserModel;
import cn.com.easy.permission.web.dto.MessageDTO;
import cn.com.easy.persistence.listener.BaseEntityListener;
import cn.com.easy.utils.RequestUtils;
import cn.com.easy.utils.ResponseOutputUtils;
import cn.com.easy.utils.SecurityUtils;

import com.google.common.collect.Lists;

/**
 * 安全认证、授权过滤器
 * 
 * @author nibili 2014-12-20
 * 
 */
@Component
public class SecurityFilter extends OncePerRequestFilter {

	/** 是否已初始化 */
	private boolean isExternalUrlsInit = false;
	/** 认证排除不过滤的链接 */
	@Value("${manage.external.authentication.filter.url}")
	private String externalAuthenticationUrlsString;
	/** 认证要排除的url列表 */
	private List<String> externalAuthenticationUrls;
	/** 授权排除不过滤的链接 */
	@Value("${manage.external.authorization.filter.url}")
	private String externalAuthorizationUrlsString;
	/** 认证要排除的url列表 */
	private List<String> externalAuthorizationUrls;

	@Override
	@Transactional(rollbackFor = Exception.class)
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
		UserModel userModel = ((UserModel) RequestUtils.getCurrentUser(request));
		if (userModel != null) {
			BaseEntityListener.userIdThreadLocal.set(userModel.getId());
			BaseEntityListener.userNameThreadLocal.set(userModel.getLoginname() + "-" + userModel.getRealname());
		}
		if (userModel == null) {
			// 未登录的全部到登录页面
			((HttpServletResponse) response).sendRedirect("/manage/login");
		} else if (userModel.getLoginname().equals("admin") == true || (userModel.getIsAdmin() != null && userModel.getIsAdmin() == true)) {
			// admin 或者 管理员 直接过
			filterChain.doFilter(request, response);
		} else if (userModel.getLoginname().equals("admin") == false && userModel.getPassword().equals(SecurityUtils.SHA256Normal(SecurityUtils.SHA256Normal("123456"))) == true
				&& request.getRequestURI().startsWith("/manage/system/password/reset") == false) {
			// 不是管理员，并且是初始密码，必须重置密码
			response.sendRedirect("/manage/system/password/reset?first=1");
		} else {
			// 验证权限
			this.validAuthentication(request, response, filterChain);
		}
	}

	/**
	 * 验证权限
	 * 
	 * @param request
	 * @param response
	 * @param filterChain
	 * @throws IOException
	 * @throws ServletException
	 * @auth nibili 2015年12月11日 下午11:19:59
	 */
	private void validAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException {
		// 请求链接
		String requestUri = request.getRequestURI();
		// 认证要排除的url列表
		if (externalAuthorizationUrls == null) {
			externalAuthorizationUrls = Lists.newArrayList(externalAuthorizationUrlsString.split(","));
		}
		if (externalAuthorizationUrls.contains(requestUri) == true) {
			// 在不用授权的链接中
			filterChain.doFilter(request, response);
			return;
		} else {
			// 获取当前用户的权限
			List<String> resourceModels = RequestUtils.getUserPermission(request);
			if (resourceModels != null) {

				//
				if (resourceModels.contains(requestUri) == true) {
					// 有权限直接过
					filterChain.doFilter(request, response);
				} else {
					// 没有权限，判断是html请求，还是json请求
					String acceptString = request.getHeader("Accept");
					if (acceptString.toLowerCase().indexOf("json") != -1) {
						// 是json请求，返回json格式的无权限
						ResponseOutputUtils.renderJson(response, MessageDTO.newInstance("", false, "您没有权限~"));
					} else {
						// 返回html格式的无权限
						response.sendRedirect("/403");
					}
				}
			} else {
				response.sendRedirect("/403");
			}
		}
	}

	@Override
	protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
		if (isExternalUrlsInit == false) {
			if (StringUtils.isNotBlank(externalAuthenticationUrlsString) == true) {
				externalAuthenticationUrls = Lists.newArrayList(externalAuthenticationUrlsString.split(","));
			}
			// 如果要排除过滤的路径变量是空的，则置为true，这样，下次就不会再执行这一段被始化代码
			isExternalUrlsInit = true;
		}
		String uri = request.getRequestURI();
		if (CollectionUtils.isEmpty(externalAuthenticationUrls) == false) {
			// 不为空，匹配的都不过滤，直接获取网站资源
			for (String patten : externalAuthenticationUrls) {
				if (uri.matches(patten) == true) {
					return true;
				}
			}
		}
		return false;
	}
}
